﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CommandLine;
using GurLoader.CommandLineOptions;
using GurLoader.Preferences;
using GurLoader.Service.ImgurTaskBuilder;
using Imgur.Net;
using Imgur.Net.Auth;
using Microsoft.VisualBasic.FileIO;

namespace GurLoader.Service.MessageProcessing
{
    public class MailslotMessageProcessingService : MessageProcessingService
    {
        private IDispatcher Dispatcher { get; set; }
        public MailslotMessageProcessingService(ITaskBuilderService executionService, IDispatcher dispatcher, GurLoaderPreferences preferences)
        {
            if (executionService == null)
                throw new ArgumentNullException("executionService");

            if (dispatcher == null)
                throw new ArgumentNullException("dispatcher");

            if (preferences == null)
                throw new ArgumentNullException("preferences");

            ExecutionService = executionService;
            Dispatcher = dispatcher;
            AppPreferences = preferences;
        }

        private ImgurAuthProvider ImgurAuthorizationProvider { get; set; }
        private AlbumProvider AlbumProvider { get; set; }
        private ImageProvider ImageProvider { get; set; }
        private GurLoaderPreferences AppPreferences { get; set; }

        private ITaskBuilderService ExecutionService { get; set; }

        public Task<T> ProcessMessage<T>(string commandline,
            IProgress<IDelegatingCommandProgress> progress,
            CancellationToken cancellationToken)
            where T : ImgurProcessResult
        {

            if ( string.IsNullOrEmpty(commandline) )
                throw new CommandLineParsingException("Empty command line.");

            string[] cmd;
            using (var p = new TextFieldParser(new StringReader(commandline)))
            {
                p.Delimiters = new[] {" "};
                cmd = p.ReadFields();

                List<string> cleanFields = new List<string>();
                foreach (string s in cmd)
                {
                    if (! String.IsNullOrEmpty(s))
                        cleanFields.Add(s);
                }

                cmd = cleanFields.ToArray();
            }
            
            StringWriter errorWriter = new StringWriter();
            Parser parser = new Parser(with => with.HelpWriter = errorWriter);
            var parseResult = parser.ParseArguments<SendImageOptions, SendImagesOptions, SendAlbumOptions>(cmd);
            if (parseResult.Errors.Any())
                throw new CommandLineParsingException( errorWriter.ToString() );

            var parseResultObject = (ICommandLineOptions) parseResult.Value;

            try
            {
                parseResultObject.Validate();
            }
            catch (Exception e)
            {
                throw new CommandLineParsingException("Error validating options.", e);
            }

            Task<T> task = null;

            switch (parseResultObject.CommandAction)
            {
                case Command.SendAlbum:
                {
                    SendAlbumOptions opts = (SendAlbumOptions) parseResultObject;

                    List<ImageContent> images = new List<ImageContent>();

                    foreach (var file in opts.Files)
                    {
                        try
                        {
                            //images.Add(new ImageContent(Image.FromFile(file), Path.GetFileName(file)));
                            images.Add(new ImageContent(Image.FromFile(file), file));
                        }
                        catch
                        {
                            // if there is an error loading the image we just dont process it.
                        }
                    }
                    
                    if( images.Count == 0 )
                        throw new CommandLineParsingException("Unable to find any valid files as part of command line.");

                    task = ExecutionService.UploadAlbum(images, opts.Title, opts.Description, opts.LayoutStyle, progress, cancellationToken, true, Dispatcher, AppPreferences.OpenWhenComplete) as Task<T>;
                }
                    break;
                case Command.SendImages:
                {
                    SendImagesOptions opts = (SendImagesOptions) parseResultObject;

                    List<ImageContent> images = new List<ImageContent>();

                    foreach (var file in opts.Files)
                    {
                        try
                        {
                            //images.Add(new ImageContent(Image.FromFile(file), Path.GetFileName(file)));
                            images.Add(new ImageContent(Image.FromFile(file), file));
                        }
                        catch
                        {
                            // if there is an error loading the image we just dont process it.
                        }
                    }

                    if (images.Count == 0)
                        throw new CommandLineParsingException("Unable to find any valid files as part of command line.");

                    task = ExecutionService.UploadImages(images, progress, cancellationToken, true, Dispatcher, AppPreferences.OpenWhenComplete) as Task<T>;
                }
                    break;
            }

            return task;
        }
    }
}